package jp.co.dailyReport.project;

import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import jp.co.dailyReport.ExecuterManager;
import jp.co.dailyReport.PermissionManager;
import jp.co.dailyReport.staff.Staff;
import jp.co.dailyReport.ConnectionFactory;
import jp.co.dailyReport.DataUnavailableException;
import jp.co.dailyReport.PermissionException;
import jp.co.dailyReport.project.sql.ProjectDeleteExecuter;
import jp.co.dailyReport.project.sql.ProjectUpdateExecuter;
import jp.co.dailyReport.project.sql.ProjectsLoadExecuter;
import jp.co.dailyReport.project.sql.ProjectLoadMaxIDExecuter;
import jp.co.dailyReport.project.sql.ProjectLoadExecuter;
import jp.co.dailyReport.project.sql.ProjectInsertExecuter;

/**
 * プロジェクト情報管理クラス
 */
public class ProjectManager {

	private static Logger log = Logger.getLogger(ProjectManager.class);

	/**
	 * プロジェクト情報を取得します。
	 * 
	 * @return プロジェクトオブジェクトの配列
	 * @throws DataUnavailableException
	 */
	public static Project[] load()
	 throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectsLoadExecuter projectsLoadExecuter = new ProjectsLoadExecuter();
		Object objs[] = (Object[])null;

		try {
			objs = ExecuterManager.execute(connectionFactory, projectsLoadExecuter);
		} catch(SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if(objs == null || objs.length == 0) {
			return new Project[0];
	 	} else {
			return (Project[])objs;
		}
	}

	/**
	 * 社員の権限でプロジェクト情報を取得します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param methodId 操作方法ID(PermissionManagerで定義)
	 * @return プロジェクトオブジェクトの配列
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static Project[] load(Staff staff,int methodId) throws DataUnavailableException {
		Project[] projects = load();
		ArrayList answer = new ArrayList();
		for(int i =0; i < projects.length;i++){
			if(PermissionManager.hasPermission(staff,projects[i],methodId)){
				answer.add(projects[i]);
			}
		}
		return (Project[])answer.toArray(new Project[0]);
	}

	/**
	 * 社員の権限でプロジェクト情報を取得します。
	 * 
	 * @param staff 社員オブジェクト
	 * @return プロジェクトオブジェクトの配列
	 * @throws DataUnavailableException
	 */
	public static Project[] load(Staff staff) throws DataUnavailableException {
		return load(staff,PermissionManager.METHOD_READ);
	}

	/**
	 * 社員の権限で処理に応じて指定操作可能なプロジェクト情報を取得します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param methodId 操作方法ID(PermissionManagerで定義)
	 * @param operationId 業務ID(PermissionManagerで定義)
	 * @return プロジェクトオブジェクトの配列
	 * @throws DataUnavailableException
	 */
	public static Project[] load(Staff staff,int operationId,int methodId)
		 throws DataUnavailableException {
		Project[] projects = load();
		 ArrayList answer = new ArrayList();

		if(PermissionManager.hasPermission(staff,operationId,methodId)){
			//ｱﾙﾊﾞｲﾄ、外注
			if(staff.getEmploymentSystem() != Integer.parseInt(Staff.STAFF_EMPLOYMENTSYSTEM_ID[2])){
				PjStaff[] pjStaff = PjStaffManager.getProjectId(staff.getStaffId());
				for(int i =0; i < pjStaff.length;i++){
					answer.add(load(pjStaff[i].getProjectId()));
				}
			} else {
				for(int i =0; i < projects.length;i++){
					answer.add(projects[i]);
				}
			}
		} else {
			for(int i =0; i < projects.length;i++){
				if(PermissionManager.hasPermission(staff,projects[i],methodId)){
					answer.add(projects[i]);
				}
			}
		}
		return (Project[])answer.toArray(new Project[0]);
	}

	/**
	 * プロジェクト情報を取得します。
	 * 
	 * @param projectId プロジェクトID
	 * @return プロジェクトオブジェクト
	 * @throws DataUnavailableException
	 */
	public static Project load(int projectId) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectLoadExecuter projectLoadExecuter = new ProjectLoadExecuter(projectId);
		Object objs[] = (Object[])null;

		try {
			objs = ExecuterManager.execute(connectionFactory, projectLoadExecuter);
		} catch(SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if(objs == null || objs.length == 0) {
			return new Project();
		} else {
			return (Project)objs[0];
		}

	}

	/**
	 * プロジェクトIDの最大値を取得します。
	 * 
	 * @return プロジェクトIDの最大値
	 * @throws DataUnavailableException
	 */
	public static int loadMaxID() throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectLoadMaxIDExecuter projectLoadMaxIDExecuter = new ProjectLoadMaxIDExecuter();
		Object objs[] = (Object[])null;

		try {
			objs = ExecuterManager.execute(connectionFactory, projectLoadMaxIDExecuter);
		} catch(SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if(objs == null || objs.length == 0) {
			return 0;
		} else {
			return Integer.parseInt((String)objs[0]);
		}
	}

	/**
	 * プロジェクト情報を更新します。
	 * 
	 * @param project プロジェクトオブジェクト
	 * @throws DataUnavailableException
	 */
	public static void update(Project project)
	 throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectUpdateExecuter projectUpdateExecuter = new ProjectUpdateExecuter(project);

		try {
			ExecuterManager.execute(connectionFactory, projectUpdateExecuter);
		} catch(SQLException sqle) {
			log.error(sqle.toString(), sqle);
			throw new DataUnavailableException(sqle.toString());
		}
	}

	/**
	 * 社員の権限でプロジェクト情報を更新します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param project プロジェクトオブジェクト
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static void update(Staff staff , Project project) throws DataUnavailableException ,PermissionException{
		if(PermissionManager.hasPermission(staff,project,PermissionManager.METHOD_WRITE)){
			update(project);
		} else {
			throw new PermissionException(" Permission denied to update project");
		}
	}

	/**
	 * プロジェクト情報を登録します。
	 * 
	 * @param project プロジェクトオブジェクト
	 * @throws DataUnavailableException
	 */
	public static void insert(Project project) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectInsertExecuter projectInsertExecuter = new ProjectInsertExecuter(project);
		try {
			ExecuterManager.execute(connectionFactory, projectInsertExecuter);
		} catch(SQLException sqle) {
			log.error(sqle.toString(), sqle);
			throw new DataUnavailableException(sqle.toString());
		}
	}

	/**
	 * 社員の権限でプロジェクト情報を登録します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param project プロジェクトオブジェクト
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static void insert(Staff staff , Project project) throws DataUnavailableException ,PermissionException{

		if(PermissionManager.hasPermission(staff,project,PermissionManager.METHOD_WRITE)){
			insert(project);
		} else {
			throw new PermissionException(" Permission denied to insert project");
		}
	}

	/**
	 * プロジェクト情報を削除します。
	 * 
	 * @param projectId プロジェクトID
	 * @throws DataUnavailableException
	 */
	public static void delete(int projectId) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectDeleteExecuter projectDeleteExecuter = new ProjectDeleteExecuter(projectId);

		try {
			ExecuterManager.execute(connectionFactory, projectDeleteExecuter);
		} catch(SQLException sqle) {
			log.error(sqle.toString(), sqle);
			throw new DataUnavailableException(sqle.toString());
		}
	}

	/**
	 * 社員の権限でプロジェクト情報を削除します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param project プロジェクトオブジェクト
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static void delete(Staff staff , Project project) throws DataUnavailableException ,PermissionException{
		if(PermissionManager.hasPermission(staff,project,PermissionManager.METHOD_WRITE)){
			delete(project.getProjectId());
		} else {
			throw new PermissionException(" Permission denied to delete project");
		}
	}

	/**
	 * プロジェクト情報の存在チェックを行います。
	 * 
	 * @param projectId　プロジェクトID
	 * @return true→存在する、false→存在しない
	 * @throws DataUnavailableException
	 */
	public static boolean isExist(int projectId) throws DataUnavailableException {

		boolean flg = false;
		ConnectionFactory connectionFactory = new ConnectionFactory();
		ProjectLoadExecuter projectLoadExecuter = new ProjectLoadExecuter(projectId);
		Object objs[] = (Object[])null;

		try {
			objs = ExecuterManager.execute(connectionFactory, projectLoadExecuter);
		} catch(SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if(objs != null && objs.length != 0){
			Project project = (Project)objs[0];
			flg = !project.isDelFlg();
		}

		return flg;
	}
}
